#include <iostream>
#include <limits>
#include <iomanip>
using namespace std;

// 函数：限制值在指定范围内
double clampValue(double value, double min_val = 0.0, double max_val = 255.0) {
    if (value < min_val) return min_val;
    if (value > max_val) return max_val;
    return value;
}

void changeRGB(int y, int u, int v) {
    auto R = 0.0, G = 0.0, B = 0.0;
    R = y + 1.13983 * (v - 128);
    G = y - 0.39465 * (u - 128) - 0.58060 * (v - 128);
    B = y + 2.03211 * (u - 128);

    // 限制RGB值在0-255范围内
    R = clampValue(R);
    G = clampValue(G);
    B = clampValue(B);

    cout << "\nYUV转RGB结果：" << endl;
    cout << fixed << setprecision(5);
    cout << "R: " << R << " (原始值限制在0-255范围内)" << endl;
    cout << "G: " << G << " (原始值限制在0-255范围内)" << endl;
    cout << "B: " << B << " (原始值限制在0-255范围内)" << endl;

    // 显示整数值
    cout << "\n整数RGB值：" << endl;
    cout << "R: " << static_cast<int>(R) << endl;
    cout << "G: " << static_cast<int>(G) << endl;
    cout << "B: " << static_cast<int>(B) << endl;
}

void changeYUV(int r, int g, int b) {
    auto Y = 0.0, U = 0.0, V = 0.0;
    Y = 0.299 * r + 0.587 * g + 0.114 * b;
    U = -0.14713 * r - 0.28886 * g + 0.436 * b + 128;
    V = 0.615 * r - 0.51498 * g - 0.10001 * b + 128;

    cout << "\nRGB转YUV结果：" << endl;
    cout << fixed << setprecision(5);
    cout << "Y: " << Y << endl;
    cout << "U: " << U << endl;
    cout << "V: " << V << endl;

    // 显示整数值
    cout << "\n整数YUV值：" << endl;
    cout << "Y: " << static_cast<int>(Y) << endl;
    cout << "U: " << static_cast<int>(U) << endl;
    cout << "V: " << static_cast<int>(V) << endl;
}

bool getValidInput(double &value, const string &prompt, int min = 0, int max = 255) {
    while (true) {
        cout << prompt;
        if (cin >> value) {
            if (value >= min && value <= max) {
                return true;
            }
            cout << "输入值必须在" << min << "到" << max << "之间！" << endl;
        } else {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "请输入有效的数字！" << endl;
        }
    }
}

int main() {
     /*
     * 1 获取一个值用于区分转换方式
     * 2 通过死循环来进行多次转换
     * 3 分别写两个函数进行RGB-YUN（changeYUV） / YUN-RGB （changeRGB）
     * 4 getValidInput 函数 用于判断输入的值是否是正确的且在固定值范围
     * 5 针对YUN-RGB转换时 clampValue函数用于 低于0的固定为0 高于255的固定为255
     */
    auto choice = 0;
    while (true) {
        cout << "请选择转换方式：" << endl;
        cout << "1. YUV转RGB (RGB值将限制在0-255范围内)" << endl;
        cout << "2. RGB转YUV" << endl;
        cout << "其他. 退出转换" << endl;
        cout << "请输入选择（1或2）：";
        cin >> choice;

        if (choice == 1) {
        auto y = 0., u = 0., v = 0.;
            getValidInput(y, "请输入Y值 (0-255): ", 0, 255);
            getValidInput(u, "请输入U值 (0-255): ", 0, 255);
            getValidInput(v, "请输入V值 (0-255): ", 0, 255);
            changeRGB(y, u, v);
        } else if (choice == 2) {
        auto r = 0., g = 0., b = 0.;
            getValidInput(r, "请输入R值 (0-255): ", 0, 255);
            getValidInput(g, "请输入G值 (0-255): ", 0, 255);
            getValidInput(b, "请输入B值 (0-255): ", 0, 255);
            changeYUV(r, g, b);
        } else {
            cout << "退出转换！" << endl;
            return 1;
        }
    }
}